AJAX IN JAVASCRIPT
AJAX is a way for the browser and server to exchange data without reloading the whole page.
This note explains AJAX in simple language.
You will learn:
- what AJAX is
- why AJAX is important
- how AJAX works step by step
- how to update the page without reloading
- how
fetch()is used with AJAX - the common beginner mistake with asynchronous data
- what query string parameters are
- how to use query parameters in a URL
1. What is AJAX?
AJAX means:
Asynchronous JavaScript and XML
AJAX is a way for the browser and server to exchange data without reloading the whole page.
Because of this, websites can feel faster and more interactive.
Today, AJAX usually works with JSON, not XML, but the old name stayed.
Diagram 1. Main idea of AJAX
User does something
-> JavaScript sends request
-> Server sends data back
-> Page updates without full reload
With AJAX, the page does not need to fully refresh every time data changes. Only the needed part of the interface is updated.
2. Why AJAX is useful
AJAX is useful because:
- it lets you update content dynamically
- it avoids full page reloads
- it reduces unnecessary work for the server and browser
- it is used in modern web apps like social networks, dashboards, and online stores
Diagram 2. Without AJAX vs with AJAX
Without AJAX
-> user clicks
-> whole page reloads
-> new content appears
With AJAX
-> user clicks
-> request is sent in background
-> only needed content changes
This is why AJAX is the foundation of dynamic websites.
3. How AJAX works step by step
The AJAX process can be divided into four main steps:
- the user performs an action
- JavaScript sends an HTTP request
- the server processes the request and returns JSON
- JavaScript receives the response and updates the interface
Diagram 3. Full AJAX flow
Step 1: User clicks button or submits form
-> Step 2: JavaScript sends HTTP request
-> Step 3: Server processes request
-> Step 4: Server returns JSON
-> Step 5: JavaScript updates page
The most important idea is this:
data changes, but page does not fully reload
4. Example interface
Suppose we have a button and an empty list.
HTML
<button type="button" class="btn">Fetch users</button>
<ul class="user-list"></ul>
When the user clicks the button, JavaScript will request users from the server and then show them on the page.
Diagram 4. Interface idea
Button: "Fetch users"
-> click
-> Request users from server
-> Show users inside <ul>
5. Basic AJAX request with fetch()
const fetchUsersBtn = document.querySelector(".btn");
fetchUsersBtn.addEventListener("click", () => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((response) => {
if (!response.ok) {
throw new Error(response.status);
}
return response.json();
})
.then((users) => {
console.log(users);
})
.catch((error) => console.log(error));
});
This code does these things:
- finds the button
- waits for a click
- sends a request with
fetch() - checks whether the response is successful
- converts the response into JSON
- gets the users data
- handles errors with
catch()
Diagram 5. Fetch request flow
Click button
-> fetch(...)
-> response arrives
-> check response.ok
-> response.json()
-> users data
-> use data
The users data becomes available only inside the then() callback where the promise is resolved.
6. Where to update the interface
The second then() is the place where you already have the backend data.
That means this is the correct place to:
- create HTML
- insert elements into the page
- update text
- show server results to the user
Diagram 6. Correct place for DOM update
fetch(...)
-> then(response => ...)
-> then(users => ...)
-> NOW data is available
-> update DOM here
7. Creating HTML from received data
A common pattern is:
- use
map()on the array of objects - return HTML for each object
- join the array of strings into one big string
- insert it into the DOM
Example
const fetchUsersBtn = document.querySelector(".btn");
const userList = document.querySelector(".user-list");
fetchUsersBtn.addEventListener("click", () => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((response) => {
if (!response.ok) {
throw new Error(response.status);
}
return response.json();
})
.then((users) => {
const markup = users
.map((user) => {
return `<li>
<p><b>Name</b>: ${user.name}</p>
<p><b>Email</b>: ${user.email}</p>
<p><b>Company</b>: ${user.company.name}</p>
</li>`;
})
.join("");
userList.insertAdjacentHTML("beforeend", markup);
})
.catch((error) => console.log(error));
});
Diagram 7. Data to markup flow
users array
-> map()
-> HTML string for each user
-> join("")
-> one big HTML string
-> insertAdjacentHTML(...)
-> render on page
This is a very common frontend pattern when data comes from an API.
8. Cleaner structure with functions
The code becomes easier to read when logic is moved into separate functions:
- one function for requesting data
- one function for rendering users
That is a good practice because the code becomes easier to read and easier to reuse.
Diagram 8. Better code structure
Click handler
-> fetchUsers()
-> then(users => renderUsers(users))
-> catch(error)
Easy rule:
one function = one job
9. The common beginner mistake
One of the most common mistakes is trying to use fetched data outside the then() callback in normal synchronous code.
Wrong example
let globalVar;
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then(users => {
console.log("users inside then callback: ", users);
globalVar = users;
console.log("globalVar inside fetch callback: ", globalVar);
});
console.log("globalVar outside fetch: ", globalVar); // undefined
10. Why this mistake happens
fetch() is asynchronous.
That means:
- the code outside
then()runs first - the server response comes later
- at the moment of the outer
console.log(), the variable is stillundefined
Diagram 9. Why undefined appears
Start fetch request
-> JavaScript continues immediately
-> outside console.log runs
-> globalVar is still undefined
-> later the server response arrives
-> then(...) runs
This is one of the most important rules in asynchronous JavaScript:
You cannot use async data in synchronous code before it arrives.
11. Correct way to work with fetched data
All logic that uses the received data should stay inside then(), or be passed from there into another function.
Correct example
fetch("https://jsonplaceholder.typicode.com/users")
.then((response) => response.json())
.then((users) => {
console.log("Received users:", users);
renderUsers(users);
})
.catch((error) => console.log("Error:", error));
Diagram 10. Correct async rule
fetch(...)
-> then(users => {
use users here
or pass users to another function
})
Easy rule:
Data from fetch is available inside then()
12. Query string parameters
Sometimes you want to send extra conditions with your request.
These are called query string parameters.
They are used for things like:
- limiting the number of results
- sorting data
- filtering data
Diagram 11. Query parameter idea
Base URL
-> add extra request conditions
-> server returns more specific result
13. Query parameter syntax
Rules:
- parameters start after
? - each parameter is
key=value - several parameters are separated by
&
Example
fetch("https://jsonplaceholder.typicode.com/users?_limit=7&_sort=name")
Diagram 12. Query string structure
https://jsonplaceholder.typicode.com/users?_limit=7&_sort=name
| |
| `- second parameter
`- first parameter
The symbol that starts query parameters is:
?
14. What this query does
In this example:
_limit=7
means:
- return only 7 users
And:
_sort=name
means:
- sort users by the
namefield
Diagram 13. Query example meaning
/users?_limit=7&_sort=name
-> get users
-> limit to 7
-> sort by name
15. Why query parameters are useful
They help you ask the backend for more specific data.
Instead of getting everything and processing it only on the frontend, you can ask the server for the exact form you need.
Examples:
- first 5 products
- posts sorted by date
- users filtered by role
- comments for one post
Diagram 14. Why query parameters matter
Without parameters
-> server may return too much data
With parameters
-> server returns more precise data
This often makes the app more efficient and cleaner.
16. Easy memory rules
AJAX = server communication without page reload
fetch() = send HTTP request
then() = work with response later
catch() = handle errors
render UI = only after data arrives
? = start query parameters
& = separate query parameters
key=value = one query parameter
17. Quick summary
- AJAX is a way to exchange data with the server without reloading the page.
- AJAX is used to make websites dynamic and interactive.
- The AJAX process is: user action, request, server response, interface update.
fetch()is commonly used to perform AJAX requests.- Received data should be used inside
then()or passed from there to another function. - Using fetched data outside
then()in synchronous code is a beginner mistake. - Query parameters help limit, sort, and filter backend results.
- Query parameters start with
?, and multiple parameters are separated by&.
18. Final conclusion
If you understand these ideas:
AJAX
fetch
then
async data
DOM update
query parameters
then you already have a strong foundation for working with dynamic data in JavaScript.
AJAX is one of the most important frontend topics because modern websites constantly load and update data without reloading the whole page.